import { ConfigService } from '@nestjs/config'
import { HttpException, HttpStatus, NotFoundException } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { User, UserDocument } from '../model/UserSchema.Schema'
import { SubBar, SubBarDoucment } from '../model/subBar.schema'
import { Friend, friendDocument } from '../model/friend.schema'
import { Inform, informDocument } from '../model/inform.schema'
import { FriendVerify, friendVerifyDocument } from '../model/friendVerify.schema'
import { Model } from 'mongoose'
import { getUserInfo, loginDto, RequestFriendType } from './UserDto'
import { hash, verify } from '../util/crypto'
import { JwtService } from '@nestjs/jwt'
export class UserService {
  constructor(
    @InjectModel(User.name) private readonly UserSchme: Model<UserDocument>,
    @InjectModel(SubBar.name) private readonly subBar: Model<SubBarDoucment>,
    @InjectModel(Friend.name) private friend: Model<friendDocument>,
    @InjectModel(Inform.name) private inform: Model<informDocument>,
    @InjectModel(FriendVerify.name) private friendVerify: Model<friendVerifyDocument>,
    private readonly jwtService: JwtService,
    private readonly configService: ConfigService,
  ) {}

  //注册
  async register(info: getUserInfo) {
    //加密
    const hashPassword = await hash(info.password)
    info.password = hashPassword
    const result = await this.UserSchme.create(info)

    return result
  }

  //登录
  async login(info: loginDto) {
    const result = await this.UserSchme.findOne({ email: info.email })
    if (!result) {
      throw new HttpException('该用户未注册', HttpStatus.BAD_REQUEST)
    }
    //解析密码
    const password = await verify(info.password, result.password)

    if (!password) {
      throw new HttpException('密码错误', HttpStatus.BAD_REQUEST)
    }
    const playload = { username: result.username, sub: result._id }
    //生成jwt
    const token = this.jwtService.sign(playload)
    return {
      data: {
        token,
      },
      message: '登录成功',
      code: 200,
    }
  }

  /* 查询关注的贴吧列表 */
  async getSubBarList(info: { page: number; pagesize: number; userID: string }) {
    const { page = 1, pagesize = 10, userID } = info
    //关联查询
    const back = await this.subBar
      .find({ user: userID }, '-__v -createdAt -updatedAt')
      .skip((page - 1) * pagesize)
      .limit(pagesize)
      .populate('bar', 'barName barLogo')
      .orFail(new NotFoundException('Not Found'))

    return {
      data: back,
      code: 200,
      message: '查询成功',
    }
  }

  /* 查询用户 */
  async findUser(username: string, page = 1, pagesize = 5) {
    const findBack = await this.UserSchme.find({ username: { $regex: username, $options: 'i' } }, 'username photo')
      .skip((page - 1) * pagesize)
      .limit(pagesize)
      .orFail(new NotFoundException('not find user'))

    return {
      data: findBack,
      code: 200,
      message: '查询成功',
    }
  }

  /* 发送添加好友申请 */
  async requestFriend(info: RequestFriendType) {
    const back = await this.friendVerify.create({ user: info.user, friend: info.friend })
    const result = await this.friendVerify
      .findById(back._id, '-__v')
      .populate('user', 'username photo')
      .populate('friend', 'username photo')
      .orFail(new NotFoundException('not found verify'))
    return {
      data: result,
      code: 200,
      message: '成功发送好友申请',
    }
  }

  /* 获取好友验证列表 */
  async getVerifyList(userID: string, page = 1) {
    //查找申请添加自己好友的
    const list = await this.friendVerify
      .find({ friend: userID.toString() }, '-__v -updatedAt')
      .skip((page - 1) * 5)
      .limit(5)
      .populate('user', 'username photo')
      .orFail(new NotFoundException('not found'))
    return {
      data: list,
      code: 200,
      message: '查询成功',
    }
  }

  /* 同意好友申请 */
  async agreeRequest(verifyID: string, myselfID: string) {
    const result = await this.friendVerify.findById(verifyID).orFail(new NotFoundException('not found'))
    //查询用户是否存在
    await this.friend.findById(result.friend).orFail(new NotFoundException('未找到添加用户'))

    result.agree = true //改变申请状态
    const back = await result.save()
    //c创建好友信息
    await this.friend.create({ myself: myselfID, friend: result.user })

    return {
      data: back,
      code: 200,
      message: '同意好友申请',
    }
  }

  /* 获取好友列表 */
  async getFriendList(myselfID: string) {
    const list = await this.friend
      .find({ myself: myselfID }, 'friend createdAt')
      .populate('friend', 'username photo')
      .orFail(new NotFoundException('not found friend'))

    return {
      data: list,
      code: 200,
      message: '好友列表获取成功',
    }
  }

  /* 拒绝好友申请 | 删除好友验证记录 */
  async rejectFriend(verifyID: string, userID: string) {
    const back = await this.friendVerify.findById(verifyID).orFail(new NotFoundException('not found'))
    if (back.friend.toString() !== userID.toString()) {
      //不相等表示不是被添加者
      throw new HttpException('权限不足', HttpStatus.BAD_REQUEST)
    }
    await back.remove()

    return {
      code: 200,
      message: '拒绝好友申请,删除好友验证纪律',
    }
  }

  async deleteFriend(myselfID: string, friendID: string) {
    const msg = await this.friend
      .findOne({ myself: myselfID, friend: friendID })
      .orFail(new NotFoundException('not find friend'))
    //删除好友
    await msg.remove()

    return {
      code: 200,
      message: '删除成功',
    }
  }
}
